'''
测试aws挑战
'''

import requests
import json
import time
import js_inject
from selenium import webdriver
from selenium.webdriver.chrome.service import Service
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import re
from bs4 import BeautifulSoup

aws_challenge_task = "https://api.capmonster.cloud/createTask"
aws_challenge_result = "https://api.capmonster.cloud/getTaskResult"
aws_key = "7b0f2915999af572c26eec84b4ec012a"

target_path = "https://nft.porsche.com/onboarding@6"
capsolver_key = "CAP-147149A8FD7E82B0A83BCD2E317C51AB2D5060780317C5C0488E4DBBFF596609"

# 启动浏览器
options = webdriver.ChromeOptions()
# options.add_argument('--proxy-server=http://127.0.0.1:7890')
options.add_argument('--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36')
# options.add_argument('--lang=ja-JP')
options.add_argument("--start-maximized")
options.add_experimental_option("excludeSwitches", ["enable-automation"])
options.add_experimental_option('useAutomationExtension', False)
options.add_argument("--disable-blink-features=AutomationControlled")
service = Service(executable_path="E:\\develop\\tool\\chromedriver\\chromedriver.exe")
options.set_capability('goog:loggingPrefs', {'performance': 'ALL'})
driver = webdriver.Chrome(options=options, service=service)

headers = {

    'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
    'accept-encoding': 'gzip, deflate, br, zstd',
    'accept-language': 'zh-CN,zh;q=0.9',
    'cache-control': 'max-age=0',
    'cookie': '_ga=GA1.2.309142006.1762075975; _ga_5E5M0SZ3LV=GS2.2.s1762075976$o1$g1$t1762077093$j60$l0$h0; aws-waf-token=dbdd6af8-cca7-402f-a6a9-286ec762acee:AQoAuIJKw85AAAAA:p3iGXkQXk7g+aVtSLfOx89tjIOSuIZBM0zUF1gv3Ztav9dB/HaCWMIQVrsySOHcVOgELaBtmwi+K/cm7pZQIm1y+oWrUdERu5Ju9QNEhS4yfOtGiGW2eXNsaxbq98RnZo8m6wzswMnmrxyyb5QDyItMKWp7L4NqpRZihd8I05ICly0Wrw7b6qdaVFvgfyADlI18TFR1kL/7ZTkuK/jrWI5WUtuqtjce8Y/+WqaytLkPFG+/f/tDmsKulRlK5eWa2f6LvIZLBnU1aOVCk',
    'priority': 'u=0, i',
    'sec-ch-ua': '"Chromium";v="142", "Google Chrome";v="142", "Not_A Brand";v="99"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'document',
    'sec-fetch-mode': 'navigate',
    'sec-fetch-site': 'same-origin',
    'sec-fetch-user': '?1',
    'upgrade-insecure-requests': '1',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36'
}


def extract_aws_waf_info(html_content):
    """
    从 HTML 中提取 AWS WAF 挑战相关信息
    """
    soup = BeautifulSoup(html_content, 'html.parser')

    result = {
        'goku_props': None,
        'challenge_js_url': None,
        'script_functions': [],
        'captcha_url': None,
    }

    # 获取所有 script 标签
    scripts = soup.find_all('script')

    for i, script in enumerate(scripts):
        # 检查是否有 src 属性（外部脚本）
        if script.get('src'):
            src = script.get('src')
            if 'challenge.js' in src:
                result['challenge_js_url'] = src
                print(f"找到 challenge.js: {src}")
            if 'captcha.js' in src:
                result['captcha_url'] = src
        # 检查脚本内容
        if script.string:
            content = script.string.strip()

            # 提取 window.gokuProps
            if 'window.gokuProps' in content:
                print(f"在脚本 {i} 中找到 gokuProps")

                # 方法1: 使用正则表达式提取对象
                goku_match = re.search(r'window\.gokuProps\s*=\s*(\{.*?\});', content, re.DOTALL)
                if goku_match:
                    try:
                        # 注意：这里需要安全地处理，因为可能是 JavaScript 对象而不是纯 JSON
                        goku_str = goku_match.group(1)

                        # 清理 JavaScript 对象格式（处理可能的尾随逗号等）
                        goku_str = re.sub(r',\s*}', '}', goku_str)  # 修复尾随逗号
                        goku_str = re.sub(r',\s*]', ']', goku_str)

                        # 尝试解析为 JSON
                        goku_props = json.loads(goku_str)
                        result['goku_props'] = goku_props
                        print("成功解析 gokuProps:")
                        for key, value in goku_props.items():
                            print(f"  {key}: {value}")

                    except json.JSONDecodeError as e:
                        print(f"JSON 解析错误: {e}")
                        # 如果 JSON 解析失败，尝试手动提取
                        result['goku_props'] = extract_js_object_manual(content)

            # 提取函数调用信息
            if 'AwsWafIntegration' in content:
                func_calls = re.findall(r'AwsWafIntegration\.(\w+)\([^)]*\)', content)
                if func_calls:
                    result['script_functions'].extend(func_calls)
                    print(f"找到 AWS WAF 集成函数: {func_calls}")

    return result


def capsolver(results):
    payload = {
        "clientKey": capsolver_key,
        "task": {
            "type": 'AntiAwsWafTaskProxyLess',
            "websiteURL": target_path,
            "awsKey": results["goku_props"]["key"],
            "awsIv": results["goku_props"]["iv"],
            "awsContext": results["goku_props"]["context"],
            "awsChallengeJS":results["challenge_js_url"],

        }
    }

    res = requests.post("https://api.capsolver.com/createTask", json=payload)
    resp = res.json()
    task_id = resp.get("taskId")
    if not task_id:
        print("Failed to create task:", res.text)
        return
    print(f"Got taskId: {task_id} / Getting result...")

    while True:
        time.sleep(1)  # delay
        payload = {"clientKey": capsolver_key, "taskId": task_id}
        res = requests.post("https://api.capsolver.com/getTaskResult", json=payload)
        resp = res.json()
        status = resp.get("status")
        if status == "ready":
            return resp.get("solution", {}).get('cookie')
        if status == "failed" or resp.get("errorId"):
            print("Solve failed! response:", res.text)
            return

def extract_js_object_manual(js_content):
    """
    手动提取 JavaScript 对象（当 JSON 解析失败时使用）
    """
    result = {}

    # 查找 gokuProps 对象
    start = js_content.find('window.gokuProps = {')
    if start == -1:
        return result

    start += len('window.gokuProps = ')
    brace_count = 0
    in_string = False
    escape_next = False
    obj_content = []

    for i, char in enumerate(js_content[start:], start):
        if escape_next:
            escape_next = False
            continue

        if char == '\\':
            escape_next = True
        elif char == '"' and not escape_next:
            in_string = not in_string
        elif not in_string:
            if char == '{':
                brace_count += 1
            elif char == '}':
                brace_count -= 1
                if brace_count == 0:
                    obj_content.append(char)
                    break

        if brace_count >= 1:
            obj_content.append(char)

    obj_str = ''.join(obj_content)

    # 尝试用更宽松的方式解析
    try:
        # 替换单引号为双引号
        obj_str = obj_str.replace("'", '"')
        # 处理无引号的属性名
        obj_str = re.sub(r'(\w+):', r'"\1":', obj_str)
        return json.loads(obj_str)
    except:
        # 最后手段：使用正则表达式提取键值对
        return extract_key_value_pairs(obj_str)


def extract_key_value_pairs(js_obj_str):
    """
    使用正则表达式从 JS 对象字符串中提取键值对
    """
    pairs = {}
    # 匹配键值对模式
    pattern = r'(\w+)\s*:\s*"([^"]*)"'
    matches = re.findall(pattern, js_obj_str)

    for key, value in matches:
        pairs[key] = value

    return pairs


def get_aws_captcha(results):
    query = {
        "clientKey": aws_key,
        "task": {
            "type": "AmazonTask",
            "websiteURL": target_path,
            "challengeScript": results["challenge_js_url"],
            "captchaScript": results['captcha_url'],
            "websiteKey": results["goku_props"]["key"],
            "context": results["goku_props"]["context"],
            "iv": results["goku_props"]["iv"],
            "cookieSolution": True
        }
    }
    response = requests.post(url=aws_challenge_task, json=query)
    response_data = json.loads(response.text)
    print(response_data)
    if response_data['taskId'] is not None:
        taskId = response_data["taskId"]
        while True:
            query_task = {
                "clientKey": aws_key,
                "taskId": taskId
            }
            time.sleep(2)
            task_result = requests.get(url=aws_challenge_result, json=query_task)
            res = json.loads(task_result.text)
            if res["status"] == 'ready':
                solution = res["solution"]
                print(solution)
                return solution
            else:
                continue
    return None


def aws_pore():
    response = requests.Session().get(target_path, headers=headers)
    if response.status_code == 202 or "challenge" in response.text:
        results = extract_aws_waf_info(response.text)
        challenge_js_url: str = results["challenge_js_url"]
        challenge_js_url = challenge_js_url.strip()
        if results['captcha_url'] is not None:
            captcha_js_ur = results['captcha_url']
        else:
            captcha_js_ur = challenge_js_url.replace("token", "captcha").replace("challenge.js", "captcha.js")
            results["captcha_js"] = captcha_js_ur
        captcha_result = capsolver(results)
        if captcha_result:
            #cookies = captcha_result["cookies"]
            cookies = {
                'aws-waf-token': captcha_result,
            }
            voucher_url = results["challenge_js_url"].replace("challenge.js", "voucher")
            ts = requests.get(voucher_url,json=captcha_result,headers=headers,cookies=cookies)
            print(ts.text)



if __name__ == '__main__':
    start = time.time()
    aws_pore()
    end = time.time()
    print("耗时："+str(start - end))